import { useState, useEffect, useRef } from 'react'
import { v4 as uuidv4 } from 'uuid'

const FUNC_ERROR_TEXT = 'Expected a function'

const useDebounce = (value, interval = 300) => {
	const [debouncedValue, setDebouncedValue] = useState(value)
	useEffect(() => {
		const timer = setTimeout(() => {
			console.log(value, 'value')
			setDebouncedValue(value)
			clearTimeout(timer)
		}, interval)

		return () => {
			clearTimeout(timer)
		}
	}, [value, interval])

	return debouncedValue
}

const useThrottle = (value, interval = 300) => {
	const [throttleValue, setThrottleValue] = useState(value)
	const startTimeRef = useRef(new Date())

	useEffect(() => {
		let endTime = new Date()
		const startTime = startTimeRef.current
		let timer
		const diffTime = endTime - startTime
		const nextTime = interval - (endTime - startTime)
		if (diffTime >= interval) {
			setThrottleValue(value)
			startTimeRef.current = new Date()
		} else {
			timer = setTimeout(() => {
				setThrottleValue(value)
				startTimeRef.current = new Date()
			}, nextTime)
		}

		return () => {
			clearTimeout(timer)
		}
	}, [value, interval])

	return throttleValue
}

const debounce = (fn, interval) => {
	let timer = null
	if (typeof fn != 'function') {
		throw new TypeError(FUNC_ERROR_TEXT)
	}
	return async function (...args) {
		if (timer) {
			clearTimeout(timer)
		}
		// react函数定义的时候 添加event.persist() 就不需要这个了
		// for (let item of args) {
		// 	if (item.__proto__.constructor.name === 'SyntheticEvent') {
		// 		await item.persist()
		// 	}
		// }

		timer = setTimeout(() => {
			fn.apply(this, args)
			timer = null
			clearTimeout(timer)
		}, interval)
	}
}

const throttle = (fn, interval) => {
	let timer
	let startTime = new Date()
	if (typeof fn != 'function') {
		throw new TypeError(FUNC_ERROR_TEXT)
	}
	return async function (...args) {
		if (timer) {
			clearTimeout(timer)
		}

		// for (let item of args) {
		// 	if (item.__proto__.constructor.name === 'SyntheticEvent') {
		// 		await item.persist()
		// 	}
		// }

		let endTime = new Date()
		const diffTime = endTime - startTime
		const nextTime = interval - (endTime - startTime)
		if (diffTime >= interval) {
			fn.apply(this, args)
			startTime = new Date()
		} else {
			timer = setTimeout(() => {
				fn.apply(this, args)
				startTime = new Date()
				timer = null
				clearTimeout(timer)
			}, nextTime)
		}
	}
}

window.requestIdleCallback =
	window.requestIdleCallback ||
	function (handler) {
		let startTime = Date.now()

		return setTimeout(() => {
			handler({
				didTimeout: false,
				timeRemaining: function () {
					return Math.max(0, 50 - (Date.now() - startTime))
				},
			})
		}, 1)
	}

window.cancelIdleCallback =
	window.cancelIdleCallback ||
	function (id) {
		clearTimeout(id)
	}
// const tasks = []
// const someThingDeal = (deadline) => {
//   while ((deadline.timeRemaining() > 0 || deadline.didTimeout) && tasks.length > 0) {
//     doWorkIfNeeded();
//   }
//
//   if (tasks.length > 0) {
//     requestIdleCallback(myNonEssentialWork);
//   }
// }
//
// requestIdleCallback(someThingDeal, 500) // 第二个为超时时间 达到这个时间 任务直接执行

const getUId = () => {
	return uuidv4().split('-')[0]
}

// 随机布尔值
const randomBoolean = () => Math.random() >= 0.5
// 是否为工作日
const isWeekday = (date) => date.getDay() % 6 !== 0
// 反转字符串
const reverseStr = (str) => str.split('').reverse().join('')
// 检查当前Tab页是否在前台
const isBrowserTabInView = () => document.hidden
// 判断奇偶数
const evenOrOdd = (num) => (num % 2 === 0 ? 'even' : 'odd')
// 获取平均值
const getAverage = (...args) => args.reduce((prev, item) => prev + item, 0) / args.length

export { useDebounce, useThrottle, debounce, throttle, getUId }
